const { io } = require("socket.io-client");
const { DE_MAIN } = require('./config')

const centerSocket = io(`${DE_MAIN}:3001/nodes`);
const fs = require("fs");
const path = require("path");
const { RECORD_DIR, pushVision, printTip } = require('./config')

const keyChunkApi = require('./keyChunkApi')
const { getBinary } = require('./DES/index')

const { Worker } = require("worker_threads");

let NODE_ID = 'cb288d29-d275-4bde-828a-f9e76e9f3114'

const SIZE = 21
const K = '696e737069726564'
// 已知的前N个bit数
const knownK = K.substring(0, K.length - (SIZE / 7 * 2))

// 密钥二进制
const KBinary = getBinary(knownK)

// 密文，解密后的明文：positive
const ciphertext = 'f6daa309a4e78f39'

/*
关键字 含义转换
emit 触发 -- 发送
on 监听 -- 接收

node 计算节点，简写 n
center 中心服务器，简写 c

节点 向 中心服务器 发送 socket.emit(n-c-{eventName})

中心服务器 向 节点 发送 socket.emit(c-n-{eventName})

 */

function socketService(socket) {
  console.log('has conn vision');

  // 连接 中央服务器
  centerSocket.emit('n-c-conn')
  // 接受 中央服务器 返回的连接状态
  centerSocket.on('c-n-conn', data => {
    if (data.code === 2000) {

      // 推送至 vision
      socket.emit('conn', {
        localService: true,
        centerService: true
      })
    }
  })

  // 开始 计算

  socket.on('v-s-start', async () => {
    let flag = true

    while (flag) {
      // pushVision(socket, '2s后开始')
      const result = await start(socket)
      flag = result
    }

  })

  // 

}

async function start(socket) {
  pushVision(socket, '开始请求密钥块')

  const startTimestamp = Date.now();

  // 1. 获取 密钥块，携带 NODE_ID, 
  const { code, data } = await getOneChunk(NODE_ID)
  let { id, beginPos, endPos } = data
  if (!id) {
    pushVision(socket, '没有获取密钥块')
    return false
  } else {
    pushVision(socket, `以获取密钥块“${beginPos}--${endPos}”，计算中...`)
  }

  // 解密线程
  const decryptThread = new Worker(__dirname + "/decryptThread.js");
  // endPos = +beginPos + 10000
  decryptThread.postMessage({
    beginPos, endPos, KBinary, length: SIZE, ciphertext
  })



  return new Promise(async (resolve, reject) => {
    decryptThread.on('message', async (result) => {

      // 结束时间
      const endTimestamp = Date.now();

      // printTip('写入文件text')
      // const filename = path.resolve(RECORD_DIR, `${beginPos}_${endPos}_data.text`)
      // fs.writeFileSync(filename, JSON.stringify(re))
      // printTip('写入完成')

      // printTip('写入文件JSON')
      // const filename_JSON = path.resolve(RECORD_DIR, `${beginPos}_${endPos}_data.json`)
      // fs.writeFileSync(filename_JSON, JSON.stringify(result))
      // printTip('写入完成')

      const right = result.filter(item => {
        return item.verify === true
      })

      // 返回 chunk 的计算结果
      pushVision(socket, '发送计算结果给中心服务器')

      let reserve = {
        'node_id': NODE_ID, // 计算的节点 编号
        'right_length': right.length, // 匹配的结果
        'size_length': result.length // 密钥块 存在的密钥长度
      }
      const putData = {
        result: endTimestamp - startTimestamp, // 单位毫秒
        status: 2,
        id: id,
        reserve: JSON.stringify(reserve),
        right: JSON.stringify(right)
      }
      const { code } = await keyChunkApi.putOneChunk(putData)
      if (code === 2000) {
        pushVision(socket, '发送成功')
      }

      // printTip('写入文件right_JSON')
      // const filename_JSON_right = path.resolve(RECORD_DIR, `${beginPos}_${endPos}_right_data.json`)
      // fs.writeFileSync(filename_JSON_right, JSON.stringify(right))
      // printTip('写入完成')

      pushVision(socket, '计算完成')
      pushVision(socket, '开始请求下一次')

      resolve(true)
    })
  })



  // const result = decrypter({
  //   beginPos, endPos, KBinary, length: SIZE, ciphertext, socket
  // })




}

/**
 * 获得一个密钥块的信息
 * @returns 
 */
async function getOneChunk() {
  const data = await keyChunkApi.getOneChunk(NODE_ID)
  return data
}



module.exports = socketService

/*
1. 第一次获取
2. 计算
3. 计算完成，发送检验正确的结果，
4. 返回第 1. 不
 */


process.on('uncaughtException', function (err) {
  console.log(err);
  debugger
})

// getChunkOne().then(re => {
//   console.log(re);
// })
